
/**
  ******************************************************************************
  * @file    can_open.h
  * @author  Dajin Li
  * @version V0.0.1
  * @date    08-08-2015 
  * @brief   This file contains CANopen specific functions.  
  *          
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; KION(SZ) R&D Center
  *
  * Licensed under KION, (the "License");
  *
  ******************************************************************************
  */

#ifndef CAN_OPEN_H
#define CAN_OPEN_H


/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "Global.h"
#include "var_tbl.h"

/********************************************************************************************************
*Macros
********************************************************************************************************/
// Mailbox definitions
#define CANOPEN_EMERGENCY_RCV                           0x12    // Emergency message receive mailbox
#define CANOPEN_EMERGENCY                               0x13    // Emergency message transmit mailbox
#define CANOPEN_NMT                                     0x14    // NMT message receive mailbox
#define CANOPEN_HEARTBEAT                               0x15    // Hearbeat message transmit mailbox
                                                        
#define CANOPEN_SDO_MISO                                0x16    // SDO_MISO  Service Data Object (Master In  Slave Out
#define CANOPEN_SDO_MOSI                                0x17    // SDO_MOSI  Service Data Object (Master Out Slave In)

#define CANOPEN_PDO_MISO_1                              0x18    // PDO_MISO  Process Data Object #1 (Master In  Slave Out)
#define CANOPEN_PDO_MOSI_1                              0x19    // PDO_MOSI  Service Data Object #1 (Master Out Slave In)
#define CANOPEN_PDO_MISO_2                              0x1A    // PDO_MISO  Process Data Object #2 (Master In  Slave Out)
#define CANOPEN_PDO_MOSI_2                              0x1B    // PDO_MOSI  Service Data Object #2 (Master Out Slave In)    
#define CANOPEN_PDO_MISO_3 		                        0x1C  	 // PDO_MISO  Process Data Object #3 (Master In  Slave Out)
#define CANOPEN_PDO_MOSI_3 		                        0x1D  	 // PDO_MOSI  Service Data Object #3 (Master Out Slave In)
#define CANOPEN_PDO_MISO_4 		                        0x1E  	 // PDO_MISO  Process Data Object #4 (Master In  Slave Out)
#define CANOPEN_PDO_MOSI_4 		                        0x1F  	 // PDO_MOSI  Service Data Object #4 (Master Out Slave In)
                                                        
#define CANOPEN_TRAC_CAL_TX_ID                          0x781   // To traction
#define CANOPEN_LIFT_CAL_TX_ID                          0x782   // To Tilt
#define CANOPEN_TRAC_CAL_RX_ID                          0x791   // from traction
#define CANOPEN_LIFT_CAL_RX_ID                          0x792   // from Tilt
                                                        
#define CANOPEN_TRAC_HEARTBEAT_ID                       0x708   // traction controller heartbeat id
#define CANOPEN_PUMP_HEARTBEAT_ID                       0x714   // traction controller heartbeat id
                                                        
#define CONTROLLER_NODE_ID                              0x08
#define PUMP_NODE_ID                                    0x14
                                                        
                                                        
                                                        
// For all the truck                 
#define DISP_KWP_RX_ID_ALL                              0x780   // KWP RX Id

#define DISP_KWP_RX_ID                                  0x784   // KWP RX Id
#define DISP_KWP_TX_ID                                  0x794   // KWP TX Id

#define DISP_KWP_INIT01_RX_ID_ALL                       0x3E4   // KWP init01 rx id
#define DISP_KWP_INIT01_TX_ID_ALL                       0x3F4   // KWP init01 tx id

                                                        
#define KWP_SINGLE_FRM                                  0x00    // single frame
#define KWP_FIRST_FRM                                   0x01    // first frame-segmented transfer
#define CONSECUTIVE_FRM                                 0x02    // flow control frame
#define KWP_FLOW_CONTROL_FRM                            0x03    // flow control frame
                                                        
#define CONTINUE_TO_SEND                                0x00    // continue to send
                                                        
#define KWP_FUN_NOT_SUPPORT                             0x12
#define KWP_SERVICE_NOT_SUPPORT                         0x11
#define KWP_GENERAL_REJECT                              0x10
#define KWP_BUSY                                        0x21
#define KWP_SEQUECNCE_ERROR                             0x22
#define KWP_SERVICE_IN_PROGRESS                         0x23
#define KWP_OUTOF_RAGNGE                                0x31
#define KWP_SECURITY_DENIED                             0x33
#define KWP_INVALID_KEY                                 0x35
#define KWP_EXCEED_ATTEMPTS                             0x36
#define KWP_NOT_EXPIRED                                 0x37
#define KWP_DOWNLOAD_NOT_ALLOW                          0x40
#define KWP_DOWNLOAD_TYPE_ERROR                         0x41
#define KWP_DOWNLOAD_ADDR_ERROR                         0x42
#define KWP_DOWNLOAD_BYTES_ERROR                        0x43
#define KWP_UPLOAD_NOT_ALLOW                            0x51
#define KWP_UPLOAD_ADDR_ERROR                           0x52
#define KWP_UPLOAD_BYTES_ERROR                          0x53


// Externally Declared Constants
#define NMT_INITIALIZATION				                0
#define NMT_STOPPED						                4
#define NMT_OPERATIONAL					                5
#define NMT_PRE_OPERATIONAL				                127


// This value MUST be the same as the VCL_CONST definition in CAN_OPEN.C
#define SUPPRESS_CAN_OPEN_KEY                           1
                                                        
                                                        
#define SDO_NO_RESPONSE_SENT_YET                        1
#define SDO_RESPONSE_HAS_BEEN_SENT                      2

// These are the control specifiers passed by the master to force entry into a state
#define NMT_CS_START_REMOTE_NODE                        1
#define NMT_CS_STOP_REMOTE_NODE                         2
#define NMT_CS_ENTER_PRE_OPERATIONAL                    128
#define NMT_CS_RESET_NODE                               129
#define NMT_CS_RESET_COMMUNICATION                      130

// * These are the state definitions reported in can_nmt_state
#define NMT_INITIALIZATION		                        0
#define NMT_STOPPED				                        4
#define NMT_OPERATIONAL			                        5
#define NMT_PRE_OPERATIONAL		                        127
#define SIGNATURE_ADDRESS                               0x0
#define CANOPEN_PDO_MAP_MAX                             0x08
#define EXT_ID_SHIFT                                    3
#define STD_MASK                                        0xFFE0 // 1111 1111 1110 // message type 1111 11 master id 11111 slave id 
#define STD_MASK1                                       0xFFC0 // 1111 1111 1100 // message type 1111 11 master id 11111 slave id 
                                                        
#define HEARTBEAT_MASK                                  0xF000 // 1111 1111 1110 // message type 1111 00 master id 00000 slave id 
                                                        
#define SHIFT_5_BITS                                    5
                                                        
#define STD_MASK_PDO                                    0xFE00 // 1111 1110 0000 0000//
                                                        
                                                        
#define CANOPEN_PDO_MAP_BASE                            0x18    // Start of PDO Mailbox Registers
                                                        
#define CANOPEN_PDO_MAP_MISO_1                          0x00    // MAP_MISO_1
#define CANOPEN_PDO_MAP_MOSI_1                          0x01    // MAP_MOSI_1
#define CANOPEN_PDO_MAP_MISO_2                          0x02    // MAP_MISO_2
#define CANOPEN_PDO_MAP_MOSI_2                          0x03    // MAP_MOSI_2
#define CANOPEN_PDO_MAP_MISO_3                          0x04    // MAP_MISO_3
#define CANOPEN_PDO_MAP_MOSI_3                          0x05    // MAP_MOSI_3
#define CANOPEN_PDO_MAP_MISO_4                          0x06    // MAP_MISO_4
#define CANOPEN_PDO_MAP_MOSI_4                          0x07    // MAP_MOSI_4
                                                        
#define CAN_PDO_MISO_1_MAP_BASE                         0x1A00
#define MSG_TYPE_MASK                                   0x780
                                                        
#define CAN_OPEN_NMT_ENABLED                            0x0001
#define CAN_OPEN_SDO_ENABLED                            0x0002
#define CAN_OPEN_PDO_ENABLED                            0x0004
#define CAN_OPEN_HEARTBEAT_ENABLED                      0x0008
#define CAN_OPEN_EMERGENCY_ENABLED                      0x0010
#define CAN_OPEN_EMERGENCY_RCV_ENABLED                  0x0020
#define CANOPEN_HEARTBEAT_RCV_ENABLED                   0x0040
#define CAN_OPEN_ENABLED                                0x0100

#define SBU_BYTE_COUNT_MAX                              8
#define SBU_BLOCK_COUNT_OFFSET_IN_OVERALL_HEADER        4
#define SBU_SEGMENT_HEADER_LENGTH                       12
                                                        
//SDO command                                           
#define SDO_WRITE                                       0x20
#define SDO_READ                                        0x40
#define SDO_BLOCK_DOWNLOAD                              0xC0
#define SDO_ABORT                                       0x80
#define SDO_BLOCK_UPLOAD                                0xA0
#define SDO_UPLOAD_BLOCK_START                          0x03
#define SDO_UPLOAD_BLOCK_RESPONSE                       0x02
#define SDO_UPLOAD_BLOCK_FINISH                         0x01
#define SDO_BOOT_CMD                                    0x22
                                                        
//SDO response                                          
#define SDO_ERROR                                       0x80
#define SDO_OK                                          0x60
#define SDO_READ_OK                                     0x42
#define SDO_DOWNLOAD_OK                                 0xA0
                                                        
                                                        
//SDO error type                                        
#define OBJECT_READ_ONLY_ERROR                          0x06010002 
#define OBJECT_NOT_EXIST_ERROR                          0x06020000
#define OBJECT_UNSUPPORTED_ACCESS                       0x06010000
#define OBJECT_MAPPED_ERROR                             0x06040041
#define OBJECT_HARDWARE_ERROR                           0x06060000
#define OBJECT_WRITE_OK                                 0x00000000
#define SEQUENCE_NUMBER_ERROR                           0x05040003
#define UNKNOWN_COMMAND                                 0x05040001 
#define ABORT_COMMAND                                   0x00000008 
#define INDEX_NOT_EXIST_ERROR                           0x06090011
#define SDO_DOWN_OK_RESPONSE                            0x0000007f
                                                        
                                                        
#define SDO_BLK_DOWNLOAD_INDEX                          0x300500
#define SDO_BLK_DISCONNECT                              0xD9
#define SDO_BLK_DISCONNECT_OK_RESPONSE                  0x000000a1
                                                        
#define KWP_RD_ECU                                      0x1A  // read ecu
#define RD_ECU_OK                                       0x5A
#define KWP_FAIL                                        0x7F
                                                        
#define KWP_RD_DATA                                     0x21   // Read data by local id
#define KWP_RD_DATA_OK                                  0x61
                                                        
#define KWP_WR_DATA                                     0x3B   // write data by local id
#define KWP_WR_DATA_OK                                  0x7B
                                                        
#define KWP_SECURITY                                    0x27
#define KWP_SECURITY_OK                                 0x67
                                                        
#define KWP_ECU_RESET                                   0x11                      
#define KWP_ECU_RESET_OK                                0x51 
                                                        
#define KWP_START_ROUTINE                               0x31  // read ecu
#define KWP_START_ROUTINE_OK                            0x71


#define KWP_START_PROGRAMMING                           0x10  // read ecu
#define KWP_START_PROGRAMMING_OK                        0x50  // read ecu


#define KWP_REQ_DOWNLOAD                                0x34  // read ecu
#define KWP_REQ_DOWNLOAD_OK                             0x74  // read ecu


#define KWP_START_FLASH                                 0x01   
#define KWP_DEL_FLASH                                   0x02  
#define KWP_CAL_CHECKSUM                                0x03  
#define KWP_PASSIVE_MODE                                0x04    
#define KWP_INIT01                                      0x80                                                        
#define KWP_EMERGENCY_FLASH                             0xFB                                                        

#define KWP_ROUTINE_INC_1                               0x10  // Increase with step 1
#define KWP_ROUTINE_INC_10                              0x11  // Increase with step 10
#define KWP_ROUTINE_DEC_1                               0x12  // Dec with step 1
#define KWP_ROUTINE_DEC_10                              0x13  // Increase with step 10
#define KWP_ROUTINE_SET_DEF                             0x18  // set default
#define KWP_ROUTINE_RESET_DEF                           0xF0  // reset to default
#define KWP_REQUEST_OUT_OF_RANGE                        0x31
                                                        
#define KWP_RD_DTC                                      0x13  // read DTC
#define KWP_RD_DTC_OK                                   0x53  // read DTC
                                                        
#define KWP_RD_SDTC                                     0x17  // read status of DTC
#define KWP_RD_SDTC_OK                                  0x57  // read status of DTC

#define KWP_CLR_DTC                                     0x14  // clear DTC
#define KWP_CLR_DTC_OK                                  0x54  // clear DTC
                                                        
#define KWP_RD_ACT_DTC                                  0x01  // read active DTC
#define KWP_RD_STORED_DTC                               0x02  // DTCs stored since last service
#define KWP_RD_ALL_STORED_DTC                           0x03  // DTCs stored since last service
                                                        
#define KWP_START_DEFAULT_SESSION                       0x10
#define KWP_DEFAULT_SESSION                             0x81
#define KWP_START_PROGRAMING_SESSION                    0x85

#define KWP_START_DEFAULT_SESSION_OK                    0x50
                                                        
#define KWP_REQUEST_SEED_3                              0x03
#define KWP_SEND_KEY_4                                  0x04
                                                        
#define KWP_REQUEST_SEED_5                              0x05
#define KWP_SEND_KEY_6                                  0x06
                                                        
#define FOUR_BYTES_LEN                                  4
#define TWO_BYTES_LEN                                   2
#define ONE_BYTES_LEN                                   1
#define PDO_MAP_LEN                                     8
#define UPLOAD_APP_4ms_PRESCALE_DEF                     5
#define FILTER_MASK                                     0x7FF    // 111 1001 1111 // message type 1111 00 master id 11111 slave id 
                                                        
/* Message ID limits*/                                  
                                                        
#define CAN_LAST_STD_ID	                                ((1 << 11) - 1)
#define CAN_LAST_EXT_ID	                                ((1L << 29) - 1)
#define CAN_MSG_CENTER_SIZE                             36
                                                        
#define KWP_MIN_INTERVAL                                0x0A
                                                        
#define KWP_LEVEL_1                                     1
#define KWP_LEVEL_2                                     2
#define KWP_LEVEL_3                                     3
                                                        
#define SECURITY_ACC_ALLOW                              0x34


#define LAST_PAGE_ADDR                                  0x080FF800
#define FILE_END                                        0x80
#define BLK_END                                         0x78

#define BLK_INDEX_MASK                                  0x0F

#define BUFFER_SIZE                                     4096


/** Security Access 1/2 supported */
#define SECACC_12                                       1

/** Security Access 3/4 supported */
#define SECACC_34                                       1

/** Security Access 5/6 supported */
#define SECACC_56                                       0
#define KWP_CHKBUF_LEN                                  256 

/********************************************************************************************************
*Types
********************************************************************************************************/
/* Wake-up modes*/
enum
{
    CAN_WAKEUP_ON_EXT,
    CAN_WAKEUP_ON_CAN
};

struct pdo_map_info
{
    u8 univeral_word_byte_offset[8][4];
    u8 map_count;
    u16 variable_table_index[8];
    s32 *map_base;
};


/* Message ID types*/
enum
{
    CAN_STD_ID,
    CAN_EXT_ID
};

enum check_read_only_status_values
{
    DO_NOT_CHECK_READ_ONLY_STATUS,
    CHECK_READ_ONLY_STATUS
};
struct CAN_SYSTEM_BITS
{
    int CAN_Enabled:1;
    int PDO_Timed_Out:1;
    int Write_EE_CAN:1;
    int CAN_PDO_Timeouts_On:1;
    int CAN_PDO_Enabled:1;
    int CAN_SDO_Enabled:1;
    int CAN_SDO_Block_Download:1;
    int CAN_SDO_Block_DISConnect:1;
    int CAN_Message_Center_Unpdate:1;
};
enum sbu_states
{
    SBU_IDLE,
    SBU_WAIT_FOR_START_UPLOAD,
    SBU_WAIT_FOR_BLOCK_ACK,
    SBU_WAIT_FOR_FINISHED_ACK,
    SBU_TRANSFER_DATA
};
enum sbu_tranfer_ids
{
    TRANSFERRING_OS,
    TRANSFERRING_AP
};
enum transfer_states
{
    TRANSFER_OVERALL_HEADER,
    TRANSFER_GET_HEADER_DATA,
    TRANSFER_SEGMENT_HEADER,
    TRANSFER_SEGMENT_DATA,
    TRANSFER_DONE
};
/** Security States */
enum secacc_state
{
   secacc_state_default       =  0x00,  /**< No security level          */
   secacc_state_programming   =  0x01,  /**< Programming State          */
   secacc_state_service       =  0x03,  /**< Field Flash                */
   secacc_state_eopl          =  0x05   /**< End Of Production Line     */
};


/** Standard KWP2000 error codes */
enum kwp_response_code
{
   KWP_RESPONSE_CODE_GENERALREJECT                    = 0x10,
   KWP_RESPONSE_CODE_SERVICENOTSUPPORTED              = 0x11,
   KWP_RESPONSE_CODE_SUBFUNCTIONNOTSUPPORTED          = 0x12,
   KWP_RESPONSE_CODE_INVALIDFORMAT                    = 0x12,
   KWP_RESPONSE_CODE_BUSYREPEATREQUEST                = 0x21,
   KWP_RESPONSE_CODE_CONDITIONSNOTCORRECT             = 0x22,
   KWP_RESPONSE_CODE_REQUESTSEQUENCEERROR             = 0x22,
   KWP_RESPONSE_CODE_ROUTINENOTCOMPLETED              = 0x23,
   KWP_RESPONSE_CODE_REQUESTOUTOFRANGE                = 0x31,
   KWP_RESPONSE_CODE_RESPONSEPENDING                  = 0x78,
   KWP_RESPONSE_CODE_SERVICENOTSUPPORTEDINACTIVEMODE  = 0x80,
   KWP_RESPONSE_CODE_ACCESSDENIED                     = 0x33,
   KWP_RESPONSE_CODE_INVALIDKEY                       = 0x35,
   KWP_RESPONSE_CODE_EXCEEDNUMOFATTEMPTS              = 0x36,
   KWP_RESPONSE_CODE_TIMEDELAYNOTEXPIRED              = 0x37,
   KWP_RESPONSE_CODE_DOWNLOADNOTACCEPTED              = 0x40,
   KWP_RESPONSE_CODE_IMPROPERDOWNLOADTYPE             = 0x41,
   KWP_RESPONSE_CODE_CANNTDOWNLOADTOADDRESS           = 0x42,
   KWP_RESPONSE_CODE_CANNTDOWNLOADNUMOFBYTES          = 0x43,
   KWP_RESPONSE_CODE_UPLOADNOTACCEPTED                = 0x50,
   KWP_RESPONSE_CODE_IMPROPERUPLOADTYPE               = 0x51,
   KWP_RESPONSE_CODE_CANNTUPLOADFROMADDRESS           = 0x52,
   KWP_RESPONSE_CODE_CANNTUPLOADNUMOFBYTES            = 0x53,
   KWP_RESPONSE_CODE_TRANSFERSUSPENDED                = 0x71,
   KWP_RESPONSE_CODE_TRANSFERABORTED                  = 0x72,
   KWP_RESPONSE_CODE_ILLEGALADDRESSINBLOCKTRANSFER    = 0x74,
   KWP_RESPONSE_CODE_ILLEGALBYTECOUNTINBLOCKTRANSFER  = 0x75,
   KWP_RESPONSE_CODE_ILLEGALBLOCKTRANSFERTYPE         = 0x76,
   KWP_RESPONSE_CODE_BLOCKTRANSFERDATACHECKSUMERROR   = 0x77,
   KWP_RESPONSE_CODE_INCORRECTBYTECNTDGBLOCKTRANSFER  = 0x79,
   KWP_RESPONSE_CODE_INVALIDCHECKSUM                  = 0xFB,
   KWP_RESPONSE_CODE_NONE                             = 0x00
};



enum kwpdiag_sid
{
    startDiagnosticSession              = 0x10,
    ecuReset                            = 0x11,
    readDiagnosticTroubleCodes          = 0x13,
    clearDiagnosticInformation          = 0x14,
    readStatusOfDiagnosticTroubleCodes  = 0x17,
    readDiagnosticTroubleCodesByStatus  = 0x18,
    readECUIdentification               = 0x1A,
    stopDiagnosticSession               = 0x20,
    readDataByLocalIdentifier           = 0x21,
    readMemoryByAddress                 = 0x23,
    securityAccess                      = 0x27,
    inputOutputControlByLocalIdentifier = 0x30,
    startRoutineByLocalIdentifier       = 0x31,
    requestDownload                     = 0x34,
    transferData                        = 0x36,
    requestTransferExit                 = 0x37,
    writeDataByLocalIdentifier          = 0x3B,
    testerPresent                       = 0x3E
};


enum kwptp_state
{
    kwptp_state_idle,
    kwptp_state_flow_control,
    kwptp_state_sendig,
    kwptp_state_waiting_for_flow_ctrl,
    kwptp_state_rx_completed,
    kwptp_state_aborted,
    kwptp_state_timeout
};

union CAN_SYSTEM_FLAGS
{
    s16                     all;
    struct CAN_SYSTEM_BITS  bit;
};
union all_types
{
    u8 char_val[4];
    u16 int_val[2];
    u32 long_val;
};
#define CAN_Enabled                     CanSystemFlags.bit.CAN_Enabled
#define PDO_Timed_Out                   CanSystemFlags.bit.PDO_Timed_Out
#define Write_EE_CAN                    CanSystemFlags.bit.Write_EE_CAN
#define CAN_PDO_Timeouts_On             CanSystemFlags.bit.CAN_PDO_Timeouts_On
#define CAN_PDO_Enabled                 CanSystemFlags.bit.CAN_PDO_Enabled
#define CAN_SDO_Enabled                 CanSystemFlags.bit.CAN_SDO_Enabled
#define CAN_SDO_Blk_Download            CanSystemFlags.bit.CAN_SDO_Block_Download
#define CAN_SDO_Blk_DISConnect          CanSystemFlags.bit.CAN_SDO_Block_DISConnect

#define Accelerator_Cal_Cmd             1
#define Joystick_Cal_Cmd                2
#define Tilt_Cal_Cmd_Step1              3
#define Tilt_Cal_Cmd_Step2              4
#define Tilt_Cal_Cmd_Step3              5
#define Steer_Sns_Cal_Cmd_Step1         6
#define Steer_Sns_Cal_Cmd_Step2         7


#define Cal_Cmd_Final_Step              0xFF

#define CAL_OK                          1
#define CAL_FAIL                        2

#define	E_TX_BUFF_SIZE	                10

/** Fortune object */
struct fortune
{
   u32 random;
};

/********************************************************************************************************
*Glboal variables
********************************************************************************************************/
extern u8 sdo_data[];


extern union CAN_SYSTEM_FLAGS CanSystemFlags;

extern s16 canopen_heart_beat_rate;                     
extern s16 canopen_emergency_rate;                      
extern s16 can_pdo_timeout_period;                      
extern s8 kwp_needs_ee;

extern u8 kwp_ee_index;
extern u8 cal_cmd;
extern u8 cal_response;
extern u8 sdo_data[];
extern u8 start_programing;
extern struct fortune fortune_fate;


/********************************************************************************************************
*Glboal functions
********************************************************************************************************/
extern int canopen_init(void);
extern void process_msg(CanRxMsg* RxMessage);
extern void process_rx_heartbeat_timeout(void);
extern void tx_msg_from_buff(void);
extern void send_canopen_msg(void);
extern void tx_msg_from_buff(void);
extern void send_kwp_response(void);
void secacc_set_state( enum secacc_state state );
void Multi_msg_send(void);

#endif // CAN_OPEN_H 

